#include <fstream>
#include <filesystem>
#include <vector>
#include <thread>
#include <coreai/speech/synthesizer.h>
#include <gio/gio.h>

static void writeBinaryDataToFile(const std::string &filename,
                                  const std::vector<char> &data) {
    if (data.size() == 0) {
        fprintf(stderr, "Data is empty!\n");
        return;
    }
    std::ofstream outputFile(filename, std::ios::out | std::ios::binary | std::ios::app);
    if (!outputFile.is_open()) {
        fprintf(stderr, "File open failed!\n");
        return;
    }
    outputFile.write(data.data(), data.size());
    // 检查是否写入成功

    if (!outputFile.good()) {
        fprintf(stderr, "Error occurred while writing to file.\n");
    }

    outputFile.close();
}

void onSynthesisResult(SpeechSynthesisResult *result, void *userData) {
    fprintf(stdout, "Start writing the synthesized results to a file.\n");

    const char *userdata = static_cast<const char*>(userData);

    uint32_t audioDataLength;
    const uint8_t* audioData = speech_synthesis_result_get_data(result, &audioDataLength);
    SpeechResultReason resultType = speech_synthesis_result_get_reason(result);

    std::fprintf(
        stdout,
        "test Synthesis result reason=%i audioDataLength=%i userData=%s \n",
        (int)resultType, (int)audioDataLength, userdata);

    std::vector<char> data {audioData, audioData + audioDataLength };
    writeBinaryDataToFile("../testsynthesis.pcm", data);

    fprintf(stdout, "Write completed.\n");
}

void testSynthesisOutputPcmData() {
    GMainLoop *pMainLoop = g_main_loop_new(nullptr, false);

    auto *synthesizerConfig = audio_config_create_audio_output_from_pcm_data();

    SpeechSynthesizerSession *synSession = speech_synthesizer_create_session();

    SpeechModelConfig *modelconfig = speech_model_config_create();
    speech_model_config_set_name(modelconfig, "讯飞-语音大模型");//或"百度-语音大模型"
    speech_model_config_set_deploy_type(modelconfig,
                                    ModelDeployType::PublicCloud);
    speech_synthesizer_set_model_config(synSession, modelconfig);

    speech_synthesizer_result_set_callback(synSession, onSynthesisResult, nullptr);
    speech_synthesizer_init_session(synSession);

    audio_config_set_input_audio_rate(synthesizerConfig, 16000);
    speech_synthesizer_set_audio_config(synSession, synthesizerConfig);

    speech_synthesizer_synthesize_text_async(synSession, "你好", 100);

    int stopErrorCode = speech_synthesizer_stop_speaking(synSession);

    g_main_loop_run(pMainLoop);
    g_main_loop_unref(pMainLoop);
}

void Test01_Synthesizer(int speed, int volume, int pitch) {
    // test synthesizer
    auto *config = audio_config_create_audio_output_from_default_speaker();

    audio_config_set_output_audio_speed(config, speed);
    audio_config_set_output_audio_volume(config, volume);
    audio_config_set_output_audio_pitch(config, pitch);

    SpeechSynthesizerSession *session = speech_synthesizer_create_session();

    std::string synthesizingResult = "synthesizing result";
    speech_synthesizer_result_set_callback(session, onSynthesisResult,
                                           (void *)synthesizingResult.c_str());

    speech_synthesizer_init_session(session);
    audio_config_set_input_audio_rate(config, 16000);
    speech_synthesizer_set_audio_config(session, config);

    std::string str =
        "你好，百度AI大模型"
        "你好，百度AI大模型";
    speech_synthesizer_synthesize_text_async(session, str.data(), str.size());
    GMainLoop *pMainLoop = g_main_loop_new(nullptr, false);

    std::thread ctrlThread([pMainLoop, &session] {
        while (std::getchar() != '\n') {
        }
        speech_synthesizer_stop_speaking(session);
        g_main_loop_quit(pMainLoop);
    });
    ctrlThread.detach();

    g_main_loop_run(pMainLoop);
    g_main_loop_unref(pMainLoop);
}

int main(int argc, char *argv[])
{
    testSynthesisOutputPcmData();

    // 语速，可选值：[0-100]，默认为50
    // 音量，可选值：[0-100]，默认为50
    // 音高，可选值：[0-100]，默认为50

//    Test01_Synthesizer(90,36,86);
    return 0;
}
